#pragma once

#ifndef _VOXELSPACE_H_
#define _VOXELSPACE_H_

#include "BBox.h"
#include <maya/MVector.h>
#include <maya/MFloatPoint.h>
#include <vector>
#include "Visualizer.h"

typedef struct {
	MFloatPoint p1;
	MFloatPoint p2;
	MFloatPoint p3;
} triangle;

typedef struct {
	triangle t;
	int object;
	int index;
} triangle_object;

class VoxelSpace
{
public:
  VoxelSpace(const BBox& box, int voxel_factor);
  ~VoxelSpace(void);

  MVector center() const;
  void get_voxel_coord(const MFloatPoint& space_coord, Idx3& vox_coord) const;
  int get_voxel_idx(const Idx3& vox_coord) const;
  Idx3 idx_3d_from_idx(int idx) const;
  void init(std::vector<std::vector<triangle>> triangles);
  void Bresenham3D(Idx3 p0, Idx3 p1, std::vector<Idx3>& points);
  bool RayCubeIntersection(MVector dir,MFloatPoint p0,float& tnear,float& tfar);
  void floatAlgo(MFloatPoint point1, MFloatPoint point2, MVector ray, std::vector<Idx3>& points, std::vector<int>& indices,  
    MFloatVector& ray_scaled, MFloatPoint& pt1_scaled, MFloatPoint& pt2_scaled);
  bool ourColsestIntersection(MVector rayDir, MFloatPoint raySource, float& minHitRayParam, int& minMesh, int& minHitTriangle, MFloatPoint& minHitPoint, float& Bary1, float& Bary2, float& Bary3);
  bool intersectsTriangle(MFloatPoint& p0, MVector& r, MFloatPoint& p1, MFloatPoint& p2, MFloatPoint& p3, MFloatPoint& p, float& mult);
  float getDiagLength() const { return m_diagLength; }
  std::vector<std::vector<triangle_object>> tri_inside_vox;
  int m_vfactor;

  const BBox& bounding_box() const { return m_bbox; }
  const MVector& inc_vec() const { return m_inc; }
   int total_voxels_for_all_rays;
  int total_polygons_for_all_rays;
  int found_intersections_with_polygons;

private:
  BBox m_bbox;
  MVector m_inc;
  Visualizer m_viz;
  float m_diagLength;
};

#endif